import pygame
import random
from game_items import*
from game_hud import*
from game_music import*
class Game(object):
    """游戏类"""
    def __init__(self):
        #游戏主窗口
        self.main_window=pygame.display.set_mode(SCREEN_RECT.size)
        pygame.display.set_caption("飞机大战")
        #游戏状态属性
        self.is_game_over=False#游戏结束标记
        self.is_pause=False#游戏暂停标记

        #精灵组属性
        self.all_group=pygame.sprite.Group()#所以精灵组
        self.enemies_group =pygame.sprite.Group()#敌机
        self.supplies_group =pygame.sprite.Group()#道具精灵组
        #创建精灵
        #背景精灵，静止不动
        # GameSprite("background.png",1,self.all_group)

        # 背景精灵，交替滚动
        self.all_group.add(Background(False),Background(True))
        #英雄精灵组，静止不动
        # hero=GameSprite("me1.png",0,self.all_group)
        # hero.rect.center=SCREEN_RECT.center#显示再屏幕中央

        #指示器面板
        self.hud_panel=HudPanel(self.all_group)
        #创建敌机
        self.create_enemies()

        #英雄精灵
        self.hero=Hero(self.all_group)
        #设置面板中炸弹数量
        self.hud_panel.show_bomb(self.hero.bomb_count)
    
        self.create_supplies()    
        
        # #测试-音乐和音效
        # #加载背景音乐文件准备播放
        # pygame.mixer.music.load("./res/sound/game_music.ogg")
        # #播放音乐
        # pygame.mixer.music.play(-1)
        # #创建声音对象
        # hero_down_sound=pygame.mixer.Sound("./res/sound/me_down.wav")
        # hero_down_sound.play()
        #创建音乐播放器
        self.player=MusicPlayer("game_music.ogg")
        self.player.play_music()


        # #将所有敌机的速度设置为0，并修改敌机的初始位置
        # for enemy in self.enemies_group.sprites():
        #     enemy.speed=0
        #     enemy.rect.y+=400
        # self.hero.speed=1

        # #英雄精灵，静止不动
        # hero=Plane(["me%d.png"% i for i in range(1,3)],self.all_group)
        # hero.rect.center=SCREEN_RECT.center#显示再屏幕中央
    
        # #英雄精灵，静止不动
        # self.hero=Plane(1000,5,0,"me_down.wav",
        #                 ["me%d.png"% i for i in range(1,3)],
        #                 "me1.png",["me_destroy_%d.png"% i for i in range(1,5)],
        #                 self.all_group)
        # self.hero.rect.center=SCREEN_RECT.center

    def reset_game(self):
        """游戏重置"""
        self.is_game_over=False
        self.is_pause=False
        self.hud_panel.reset_panel()
        self.hero.rect.midbottom=HERO_DEFAULT_MID_BOTTOM
        #清空所有敌机
        for enemy in self.enemies_group:
            enemy.kill()
        #清空残留子弹
        for bullet in self.hero.bullets_group:
            bullet.kill()
        #重新创建敌机
        self.create_enemies()

    def event_handler(self):
        """事件监听
        :return:如果监听到退出事件,返回True,否则返回False
        """
        #判断是否正在游戏
        if not self.is_game_over and not self.is_pause:
            #监听结束子弹增强效果定时器事件
            if event.type==BULLET_ENHANCED_OFF_EVENT:
               self.hero.bullets_kind=0
               pygame.time.set_timer(BULLET_ENHANCED_OFF_EVENT,0)
            #监听投放道具事件
            if event.type==THROW_SUPPLY_EVENT:
                self.player.play_sound("supply.wav")
                supply=random.choice(self.supplies_group.sprites())
                supply.throw_supply()
            #监听发射子弹事件
            if event.type==HERO_FIRE_EVENT:
                self.player.play_sound("buttet.wav")
                self.hero.fire(self.all_group)
            #监听取消英雄飞机无敌事件
            if event.type==HERO_POWER_OFF_EVENT:
                print("取消无敌状态。。。")
                #设置英雄飞机状态
                self.hero.is_power=False
                #取消定时器
                pygame.time.set_timer(HERO_POWER_OFF_EVENT,0)
                #监听英雄飞机牺牲事件
            if event.type==HERO_DEAD_EVENT:
                print("英雄牺牲了。。。")
                #生命计数-1
                self.hud_panel.lives_count-=1
                #更新生命计数显示
                self.hud_panel.show_lives()
                #更新炸弹显示
                self.hud_panel.show_bomb(self.hero.bomb_count)
            #监听玩家按下“b”键，引爆一颗炸弹
            if event.type==pygame.KEYDOWM and event.key==pygame.K_b:
                #如果英雄飞机没有牺牲同时有炸弹
                if self.hero.hp>0 and self.hero.bomb_count>0:
                    self.player.play_sound("use_bomb.wav")
                #引爆炸弹
                score=self.hero.blowup(self.enemies_group)
                #更新炸弹数量显示
                self.hud_panel.show_bomb(self.hero.bomb_count)
                #更新游戏得分，若关卡等级提升，则可创建新类型的敌机
                if self.hud_panel.increase_score(score):
                    self.create_enemies()
                # #TODO测试炸毁所有敌机
                # for enemy in self.enemies_group.sprites():
                #     enemy.hp=0
                # #TODO测试生命计数数量变化
                # self.hud_panel.lives_count=random.randint(0,10)
                # self.hud_panel.show_lives()

        for event in pygame.event.get():
            if event.type==pygame.OUIT:
                return True
            elif event.type==pygame.KEYDOWM and event.key==pygame.K_ESCAPE:
                if self.is_game_over:
                    self.reset_game()
                else:
                    self.is_pause=not self.is_pause
                    #恢复或暂停背景音乐
                    self.player.pause_music(self.is_pause)
        #         return True  
        # return False

    def start(self):
        """开始游戏"""
        clock=pygame.time.Clock()
        frame_counter=0
        while True:#事件监听
            #生命计数等于0，表示游戏结束
            self.is_game_over=self.hud_panel.lives_count=0
            if self.event_handler():
                self.hud_panel.save_best_score()
                return
            #TODO 模拟英雄飞机受伤
            self.hero.hp -=30
            
                #判断游戏状态
            if self.is_game_over:
                self.hud_panel.panel_resume(True,self.all_group)
            elif self.is_pause:
                self.hud_panel.panel_resume(False,self.all_group)
            else:
                self.hud_panel.panel_resume(self.all_group)
                #碰撞检测
                self.check_collide()
                #获取当前时刻的按键元组
                keys=pygame.key.get_pressed()
                #水平移动基数
                move_hor=keys[pygame.K_RIGHT]-keys[pygame.K_LEFT]
                #垂直移动基数
                move_ver=keys[pygame.K_DOWN]-keys[pygame.K_UP]
                # #判断是否按下右方向键
                # if keys[pygame.K_RIGHT]:
                #     self.hero.rect.x+=10
                #修改逐帧动画计数器
                frame_counter=(frame_counter+1)%FRAME_INTERVAL
                #更新all_groups中的所有精灵内容
                self.all_group.update(frame_counter==0,move_hor,move_ver)
                # #测试修改游戏得分
                # if self.hud_panel.increase_score(100):
                #     print("升级到%d"%self.hud_panel.level)
                #     self.create_enemies()
                #更新 all_group中的作业精灵内容
                self.all_group.update()
            #绘制all_group中的所以精灵
            self.all_group.draw(self.main_window)
            pygame.display.update()#更新显示
            clock.titck(60)#设置刷新帧率

    def create_enemies(self):
        """根据关卡级别创建不同数量的敌机"""
        #敌机精灵组中的精灵数量
        count =len(self.enemies_group.sprites())
        #要添加关卡级别及已有的敌机数量
        groups=(self.all_group,self.enemies_group)
        #判断关卡级别及已有的敌机数量
        if self.hud_panel.level==1 and count==0:
            for i in range(16):
                Enemy(0,3,*groups)
        elif self.hud_panel.level==2 and count==16:
            #提高敌机的最大速度
            for enemy in self.enemies_group.sprites():
                enemy.max_speed=5
            #创建敌机
            for i in range(8):
                Enemy(0,5,*groups)
            for i in range(2):
                Enemy(1,1,*groups)
        elif self.hud_panel.level==3 and count==26:
            #提高敌机的最大速度
            for enemy in self.enemies_group.sprites():
                enemy.max_speed=7 if enemy.kind==0 else 3
            #创建敌机
            for i in range(8):
                Enemy(0,7,*groups)
            for i in range(2):
                Enemy(1,3,*groups)
            for i in range(2):
                Enemy(2,1,*groups)
    def check_collide(self):
        """碰撞检测"""
        #检测英雄飞机和敌机的碰撞
        if not self.hero.is_power:
            enemies=pygame.sprite.spritecollide(self.hero,
                                                self.enemies_group,False,
                                                pygame.sprite.collide_mask)
        #过滤掉已经被摧毁的敌机
        enemies=list(filter(lambda x : x.hp>0,enemies))
        #是否撞到敌机
        if enemies:
            #播放英雄飞机被撞毁音效
            self.player.play_sound(self.hero.wav_name)
            self.hero.hp=0
        for enemy in enemies:
            enemy.hp=0
        #检测敌机是否被子弹击中
        hit_enemies=pygame.sprite.groupcollide(self.enemies_group,
                                                self.hero.bullets_group,
                                                False,False,
                                                pygame.sprite.collide_mask)
        #遍历字典
        for enemy in hit_enemies:
            if enemy.hp<=0:
                continue
        #遍历击中敌机的子弹列表
        for bullet in hit_enemies[enemy]:
            #将子弹从所有精灵组中清楚
            bullet.kill()
            #修改敌机的生命值
            enemy.hp-=bullet.damage
            if enemy.hp>0:
                continue
            if self.hud_panel.increase_score(enemy.value):
                #播放升级音效
                self.player.play_sound("upgrade.wav")
                self.create_enemies()
            #播放敌机爆炸音效
            self.player.play_sound(enemy.wav_name)
            break
        #英雄拾取道具
        supplies=pygame.sprite.groupcollide(self.hero,
                                                self.supplies_group,
                                                False,
                                                pygame.sprite.collide_mask)
        if supplies:
            supply=supplies[0]
            #播放拾取道具音效
            self.player.play_sound(supply.wav_name)
            supplies.rect.y=SCREEN_RECT.h
            if supply.kind==0:
                self.hero.bomb_count+=1
                self.hud_panel.show_bomb(self.hero.bomb_count)
            else:
                self.hero.bullets_kind=1
                pygame.time.set_timer(BULLET_ENHANCED_OFF_EVENT,8000)

    def create_supplies(self):
        """创建道具"""
        Supply(0,self.supplies_group,self.all_group)
        Supply(1,self.supplies_group,self.all_group)
        #30s投放道具定时器事件
        pygame.time.set_timer(THROW_SUPPLY_EVENT,10000)
if __name__=='__main__':
    pygame.init()
    Game().start()
    pygame.quit() 